package gui;

import gui.gui2d.ChessBoardPanel;
import gui.gui2d.GamePanel;
import gui.gui2d.Promotion;
import gui.gui2d.eventsmanager.MouseListenerSelecterPiece;
import gui.gui2d.highLevelPanels.ChatPanel;
import gui.gui2d.highLevelPanels.HistoryMovedPanel;
import gui.gui2d.highLevelPanels.InfoPanel;
import gui.gui2d.highLevelPanels.MenuPanel;
import gui.gui2d.highLevelPanels.OpponentEatenListPanel;
import gui.gui2d.highLevelPanels.PanelBackgraund;
import gui.gui2d.highLevelPanels.PlayerEatenListPanel;
import gui.gui2d.highLevelPanels.utils.GuiTrigger;
import gui.gui2d.lan.LanServersManagerPanel;
import gui.gui2d.menu.JPanelMenu;
import gui.gui2d.menu.events.MenuActionListener;

import java.awt.BorderLayout;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.io.File;
import java.util.Observable;
import java.util.Observer;






import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.swing.ImageIcon;
import javax.swing.JFrame;






import multiplayer.lan.Move;
import multiplayer.lan.ServersOnAir;
import multiplayer.lan.utility.Message;
import utility.Color;
import utility.NameMemmory;
import utility.Point;
import world.Piece;
import world.PownPromotion;
import world.gameMenager.GameManager;
import world.gameMenager.GameManager1v1Local;
import world.gameMenager.GameManagerOnLan;
import world.gameMenager.GameManagerVsPc;
import world.gameMenager.GraphicsUpdatePromotion;
import world.player.LocalPlayer;
import world.player.Player;



public class GuiManager implements Observer{
	public static String LOCAL_GAME="local";
	public static String LAN_GAME="lan";
	Sequencer seq;//audio
	JFrame mainFrame;
	JPanelMenu jPanelMenu;
	GamePanel gamePanel;
	PanelBackgraund background;
	LanServersManagerPanel lanSearchPanel;

	private MenuPanel mp ;
	private HistoryMovedPanel hmp;
	private InfoPanel ip;
	private OpponentEatenListPanel opponentEaten;
	private PlayerEatenListPanel playerEaten;
	private ChatPanel chatPanel;
	private ChessBoardPanel cbp;

	public GuiManager() {
		mainFrame= new JFrame();
		Image immagineIc=Toolkit.getDefaultToolkit().getImage("images/chess.png");
		mainFrame.setIconImage(immagineIc);
		loadFrame();	
		startSound();
		loadBackground();
	}


	private void loadFrame(){
		mainFrame.setUndecorated(true);
		//mainFrame.setSize(new Dimension(1920,1080));
		GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0];
		device.setFullScreenWindow(mainFrame);
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setLayout(new BorderLayout());
		mainFrame.revalidate();
	}

	private void loadBackground(){


		background= new PanelBackgraund();
		mainFrame.getContentPane().add(background);
		mainFrame.revalidate();
		mainFrame.repaint();
		background.setLayout(new BorderLayout());



	}

	public void removeGamePanel(){
		if(gamePanel!=null)
			gamePanel.setVisible(false);
		background.removeAll();
		//background.revalidate();

		mainFrame.revalidate();
	}

	public void setVisibleMenu(){
		jPanelMenu.setVisible(true);
		mainFrame.revalidate();
		mainFrame.repaint();
	}

	public void loadMenu() {
		jPanelMenu= new JPanelMenu();
		mainFrame.add(jPanelMenu,BorderLayout.CENTER);
	}
	public void loadMenuOnBackground(){
		jPanelMenu= new JPanelMenu();
		if(background!=null){
			background.removeAll();
		}
		background.add(jPanelMenu,BorderLayout.CENTER);
		background.revalidate();
	}

	public void loadSearchMenu(ServersOnAir soa){
		lanSearchPanel= new LanServersManagerPanel();
		soa.addObserver(lanSearchPanel);
		mainFrame.remove(jPanelMenu);
		background.removeAll();
		background.add(lanSearchPanel,BorderLayout.CENTER);
		background.revalidate();
	}

	private void loadGamePanels(final String ID){
		jPanelMenu.setVisible(false);
		gamePanel=new GamePanel(ID);

		if(ID.equals(LOCAL_GAME)){
			background.add(gamePanel,BorderLayout.CENTER);
			//background.revalidate();
			loadLocalHighLevelsComponents(ID);



		}else if(ID.equals(LAN_GAME)){
			if(lanSearchPanel!=null){
				lanSearchPanel.setVisible(false);
			}else{
				jPanelMenu.setVisible(false);
			}
			background.add(gamePanel,BorderLayout.CENTER);
			//background.revalidate();
			loadLocalHighLevelsComponents(ID);

		}


	}
	public void loadLocalHighLevelsComponents(final String id){

		mp = new MenuPanel();
		hmp = new HistoryMovedPanel();
		ip= new InfoPanel();
		opponentEaten= new OpponentEatenListPanel();
		playerEaten= new PlayerEatenListPanel();
		if(id.equals(LAN_GAME)){
			chatPanel = new ChatPanel();
			gamePanel.addChatPanel(chatPanel);
		}
		gamePanel.addMenuPanel(mp);
		gamePanel.addInfoPanel(ip);
		gamePanel.addHistoryMovedPanel(hmp);
		gamePanel.addPlayerEatenListPanel(playerEaten);
		gamePanel.addOpponentEatenListPanel(opponentEaten);
	}

	public void setBlackTurn(){
		gamePanel.setBlackTurn();
	}
	public void setWhiteTurn(){
		gamePanel.setWhiteTurn();
	}
	public void setOpponentWait(){
		gamePanel.setOpponentOnWait();
	}
	public void setPlayerWait(){
		gamePanel.setPlayerOnWait();
	}

	public void setVisible() {;
	mainFrame.setVisible(true);
	}
	public void dispose() {
		mainFrame.dispose();
		seq.close();
	}
	void startSound(){
		try {
			File f2=new File("sounds/Menu.mid");
			//MidiFileFormat mff2=MidiSystem.getMidiFileFormat(f2);
			Sequence S=MidiSystem.getSequence(f2);
			seq=MidiSystem.getSequencer();
			seq.open();
			seq.setLoopCount(1000);
			seq.setSequence(S);
			seq.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void loadLocalGame() {
		loadGamePanels(LOCAL_GAME);
	}
	public void loadRemoteGame() {
		loadGamePanels(LAN_GAME);
	}

	public void loadIAGame() {
		loadGamePanels(LOCAL_GAME);
	}
	public void addChessBoardPanel(ChessBoardPanel cbp) {
		gamePanel.addCheesBoardPanel(cbp);
		this.cbp=cbp;
		repaintChessBoardPanel();

	}

	@Override
	public void update(Observable o, Object arg1) {
		if(o instanceof GameManager && o.getClass() == GameManagerVsPc.class ){
			if(arg1 instanceof Move){
				Move m = (Move) arg1;
				gamePanel.addMoveToHystory(m.toString());
			}
			if(arg1 instanceof PownPromotion){
				PownPromotion pp = (PownPromotion) arg1;
				gamePanel.disableCheesBoardPanel();
				enableSelecterPiece(pp.getCurrentPlayer().getColor());
				gamePanel.setPlayerSelectPiece(pp.getCurrentPlayer().getColor());
			}
			if(arg1 instanceof Promotion){
				disableSelecterPiece();
			}
			if(arg1 instanceof GuiTrigger){
				GuiTrigger g =(GuiTrigger)arg1;
				if(g.getId().equals(GuiTrigger.YOU_CANT_MOVE)){
					if(g.getDate() instanceof Player){
						//Player p = (Player) g.getDate();
						gamePanel.setYouCantMove();
					}
				}else if(g.getId().equals(GuiTrigger.LAST_TO_PLAY)){
					if(g.getDate() instanceof Player){
						Player p = (Player) g.getDate();
						if(p.getColor().equals(Color.BLACK)){
							gamePanel.setWhiteTurn();
						}else if(p.getColor().equals(Color.WHITE)){
							gamePanel.setBlackTurn();
						}

					}
				}else if(g.getId().equals(GuiTrigger.NO_POSSIBLE_MOVE)){
					gamePanel.setErrorMove();
				}else if(g.getId().equals(GuiTrigger.EAT_PIECE)){
					if(g.getDate() instanceof Piece){
						Piece p = (Piece)g.getDate();
						if(p.getColor().equals(Color.BLACK)){
							gamePanel.putOpponentEaten(p.get2DPath());
						}else{
							gamePanel.putPlayerEaten(p.get2DPath());
						}
					}
				}else if(g.getId().equals(GuiTrigger.CHECK)){
					if(g.getDate() instanceof Point){
						Point p = (Point)g.getDate();
						gamePanel.setCheck(Color.BLACK, p);
					}
				}
				else if(g.getId().equals(GuiTrigger.MATE)){
					if(g.getDate() instanceof Player){
						Player p = (Player)g.getDate();
						gamePanel.setMate(p.getColor().toString());
						gamePanel.disableCheesBoardPanel();
						//gamePanel.enableEndGamePanel(s);
					}
				}
			}

		}
		
		if(o instanceof GameManager && o.getClass() == GameManager1v1Local.class ){
			if(arg1 instanceof GuiTrigger){
				GuiTrigger g =(GuiTrigger)arg1;
				if(g.getId().equals(GuiTrigger.YOU_CANT_MOVE)){
					if(g.getDate() instanceof Player){
						//Player p = (Player) g.getDate();
						gamePanel.setYouCantMove();
					}
				}else if(g.getId().equals(GuiTrigger.LAST_TO_PLAY)){
					if(g.getDate() instanceof Player){
						Player p = (Player) g.getDate();
						if(p.getColor().equals(Color.BLACK)){
							gamePanel.setWhiteTurn();
						}else if(p.getColor().equals(Color.WHITE)){
							gamePanel.setBlackTurn();
						}

					}
				}else if(g.getId().equals(GuiTrigger.NO_POSSIBLE_MOVE)){
					gamePanel.setErrorMove();
				}else if(g.getId().equals(GuiTrigger.EAT_PIECE)){
					if(g.getDate() instanceof Piece){
						Piece p = (Piece)g.getDate();
						if(p.getColor().equals(Color.BLACK)){
							gamePanel.putOpponentEaten(p.get2DPath());

						}else{
							gamePanel.putPlayerEaten(p.get2DPath());
						}
					}
				}else if(g.getId().equals(GuiTrigger.CHECK)){
					if(g.getDate() instanceof Point){
						Point p = (Point)g.getDate();
						gamePanel.setCheck(Color.BLACK, p);
					}
				}
				else if(g.getId().equals(GuiTrigger.MATE)){
					if(g.getDate() instanceof String){
						String s = (String)g.getDate();
						gamePanel.setMate(s);
						gamePanel.disableCheesBoardPanel();
					}
				}
			}
			if(arg1 instanceof Move){
				Move m = (Move) arg1;
				gamePanel.addMoveToHystory(m.toString());
			}
			if(arg1 instanceof PownPromotion){
				PownPromotion pp = (PownPromotion) arg1;
				gamePanel.disableCheesBoardPanel();
				enableSelecterPiece(pp.getCurrentPlayer().getColor());
				gamePanel.setPlayerSelectPiece(pp.getCurrentPlayer().getColor());
			}
			if(arg1 instanceof Promotion){
				disableSelecterPiece();
			}
		}
		if(o instanceof GameManager && o.getClass() == GameManagerOnLan.class ){
			if(arg1 instanceof GuiTrigger){
				GuiTrigger g =(GuiTrigger)arg1;
				if(g.getId().equals(GuiTrigger.YOU_CANT_MOVE)){
					if(g.getDate() instanceof Player){
						//Player p = (Player) g.getDate();
						gamePanel.setYouCantMove();
					}
				}else if(g.getId().equals(GuiTrigger.LAST_TO_PLAY)){
					if(g.getDate() instanceof Player){
						Player p = (Player) g.getDate();
						if(p instanceof LocalPlayer){
							gamePanel.setPlayerOnWait();
						}else{
							gamePanel.setOpponentOnWait();
						}
					}
				}else if(g.getId().equals(GuiTrigger.NO_POSSIBLE_MOVE)){
					gamePanel.setErrorMove();
				}else if(g.getId().equals(GuiTrigger.EAT_PIECE)){
					if(g.getDate() instanceof Piece){
						Piece p = (Piece)g.getDate();
						if(p.getColor().equals(Color.BLACK)){
							gamePanel.putOpponentEaten(p.get2DPath());
						}else{
							gamePanel.putPlayerEaten(p.get2DPath());
						}
					}
				}else if(g.getId().equals(GuiTrigger.MESSAGE_FROM_LOCAL)){

					String p = (String)g.getDate();
					chatPanel.addMessage(NameMemmory.getInstace().getName(),p);
				}else if(g.getId().equals(GuiTrigger.MESSAGE_FROM_REMOTE)){
					Message m =(Message) g.getDate();
					String p = m.getMessage();
					chatPanel.addMessage(m.getName(),p);
				}else if(g.getId().equals(GuiTrigger.CHECK)){
					if(g.getDate() instanceof Point){
						Point p = (Point)g.getDate();
						gamePanel.setCheck(Color.BLACK, p);
					}
				}else if(g.getId().equals(GuiTrigger.MATE)){
					if(g.getDate() instanceof Player){
						Player p = (Player)g.getDate();
						gamePanel.setMate(p);
						gamePanel.disableCheesBoardPanel();
					}
				}else if(g.getId().equals(GuiTrigger.CONNECTION_LOST)){
					if(g.getDate() instanceof String){
						String s = (String)g.getDate();
						gamePanel.setConnectionLost(s);
						gamePanel.disableCheesBoardPanel();
					}
				}
			}
			if(arg1 instanceof Move){
				Move m = (Move) arg1;
				gamePanel.addMoveToHystory(m.toString());
			}
			if(arg1 instanceof PownPromotion){
				PownPromotion pp = (PownPromotion) arg1;
				gamePanel.disableCheesBoardPanel();
				if(pp.getCurrentPlayer() instanceof LocalPlayer){
					enableSelecterPiece(pp.getCurrentPlayer().getColor());
				}
				gamePanel.setPlayerSelectPiece(pp.getCurrentPlayer().getColor());
			}
			if(arg1 instanceof Promotion){
				disableSelecterPiece();
			}
			if(arg1 instanceof GraphicsUpdatePromotion){
				GraphicsUpdatePromotion g = (GraphicsUpdatePromotion) arg1;
				gamePanel.enableCheesBoardPanel();
				cbp.replace(g);
			}

		}
	}

	public void loadSelecterPanelPieceListener(MouseListener ml){

	}

	public void loadListeners(MenuActionListener menuListener) {
		jPanelMenu.addListeners(menuListener);

	}

	public void addListenerConnectionButton(ActionListener actionListener) {
		lanSearchPanel.addButtonConnectionListener(actionListener);
	}

	public void addListenerBackButton(MouseListener ml) {
		lanSearchPanel.addButtonBackListener(ml);
	}

	public String getIp(){
		return lanSearchPanel.getIpFieldValue();
	}
	public String getName(){
		return lanSearchPanel.getNameFieldValue();
	}
	public void insertInfoOnLanServersMenager(String value){
		lanSearchPanel.insertInfo(value);

	}
	public void setInfoInConnection(){
		lanSearchPanel.infoOnConnection();
	}
	public void clearInfo(){
		lanSearchPanel.infoRemoveAll();
	}

	public void  endInfoInConnection(){
		lanSearchPanel.setEndWait(true);
		clearInfo();
	}
	public void infoNoError(String s){
		lanSearchPanel.insertInfoNoError(s);
	}
	public void disableConnectionButton(){
		lanSearchPanel.disableButton();
	}
	public void enableConnectionButton(){
		lanSearchPanel.enableButton();
	}

	public void enableSelecterPiece(Color c){
		gamePanel.enableSelecterPiecePanel(c);
	}
	public void enableExitInfoPanel(){
		gamePanel.enableExitInfoPanel();
	}
	public void disableSelecterPiece(){
		gamePanel.disableSelecterPiecePanel();
	}

	public void addListenerSelecterPiecePanel(MouseListenerSelecterPiece ml ){
		gamePanel.addListenersOfSelectionPiece(ml);
	}

	public void loadServerPanel() {
		jPanelMenu.removeSelection();

	}

	public void waitingForClient(){
		jPanelMenu.waitingForClient();
	}

	public void addListenerServerButtonConnection(MouseListener ml){
		jPanelMenu.addListenerConnection(ml);
	}

	public void addListenerServerBackButton(MouseListener ml){
		jPanelMenu.addListenerBackButton(ml);
	}
	public void addListenerServerBackButtonOnConnection(MouseListener ml){
		jPanelMenu.addListenerBackButtonOnConnection(ml);
	}

	public String getNickServerPlayer(){
		return jPanelMenu.getNickServerPlayer();
	}

	public void setErrorNick(){
		jPanelMenu.setErrorNick();
	}

	public void loadComponentMenu(){
		jPanelMenu.loadMenuPanel();
	}
	public void hidePanelMenu(){
		jPanelMenu.setVisible(false);
	}
	public void seePanelMenu(){
		jPanelMenu.setVisible(true);
	}

	public void addObserverSendButton(Observer o){
		chatPanel.addObserverSendButton(o);
	}
	public void addListenerExitMenuPanel(MouseListener ml){
		mp.addExitListener(ml);
	}


	public void addListenerOkExitPanel(MouseListener ml) {
		gamePanel.addListenerOkExitPanel(ml);

	}


	public void repaintChessBoardPanel() {
		mainFrame.revalidate();
		mainFrame.repaint();
		gamePanel.repaint();
	}


	public String getServerPort() {
		return jPanelMenu.getPortServerPlayer();
	}
}
